package lrz.shiftplanner.calendar;

import java.text.SimpleDateFormat;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;

import javax.swing.JOptionPane;
import lrz.shiftplanner.components.DayPanel;
import lrz.shiftplanner.components.Selector;


public class Day{
	private Date date;
	private DayType dayType;

	public  boolean isViolatingConstraint = false;
	
	private Month month;
	private ShiftSlots slots;

	public Day(Month month, Date date, DayType type) {
		this.date = date;
		this.dayType = type;
		this.month = month;
		slots = new ShiftSlots(type);
	}
	
	public int getNumberOfShiftTypes() {
		return DayType.getShiftTypeNumber(dayType);
	}
	
	public List<String> getShiftTypeDescriptors() {
		return DayType.getShiftTypeDescriptors(dayType);
	}
	
	public int getValidShiftTypeCount(int index) {
		return slots.getCount(ShiftType.values()[slots.getValidSlots()[index]]);
	}
	
	public int getValidShiftTypeCountRemaining(int index) {
		return -slots.getDelta(ShiftType.values()[slots.getValidSlots()[index]]);
	}
	
	public int getRemainingShiftNumber() {
		int result = 0;
		for (int i=0;i<getNumberOfShiftTypes();i++)
			result-=slots.getDelta(ShiftType.values()[slots.getValidSlots()[i]]);
		return result;
	}
	
	public int getTotalShiftNumber() {
		int result = 0;
		for (int i=0;i<getNumberOfShiftTypes();i++)
			result+=slots.getCapacity(ShiftType.values()[slots.getValidSlots()[i]]);
		return result;
	}

	public Date getDate() {
		return date;
	}

	public Month getMonth() {
		return month;
	}
	
	public DayType getDayType() {
		return dayType;
	}
	
	public void setDayType(DayType dayType) {
		this.dayType = dayType;
		slots.changeDayType(dayType);
		month.calcShiftCounts();
	}
	
	public void setOriginalDayType() {
		setDayType(HolidayCalculator.getDayType(getDate()));
	}

	
//	private String convertToHTML(String str) {
//		String result = "<html>";
//		for (int i=0;i<str.length();i++) {
//			result+=str.charAt(i);
//			if (i%2==0 && i>0)
//				result+="<br>";
//		}
//		return result;
//	}

	public DayState getState() {
		if (isViolatingConstraint)
			return DayState.Invalid;
		// Incomplete, MissingStandby, Complete, Invalid
		int[] d = slots.getDeltas();
		
		// check regular shift types
		boolean fullDay = true;
		
		// Traverse shift types, do not take "B" shift into account
		for (int i=0;i<d.length-1;i++) {
			if (d[i]!=0)
				fullDay = false;
			// OK, here we DO take into account "B" shift
			if (d[i]>=1 || d[i+1]>=1)
				return DayState.Invalid;
		}
		if (!fullDay)
			return DayState.Incomplete;
		if (fullDay && d[d.length-1]<0)
			return DayState.MissingStandby;
		return DayState.Complete;
	}
	
	public void changeShift(ShiftType shiftType, int delta) {
		slots.changeCount(shiftType, delta);
		//missingCalculated = false;
		System.out.println(month.getRemainingShiftCount() +  "/"  + month.getShiftCount());
		month.setRemainingShiftCount(month.getRemainingShiftCount()-delta);
		
	}

	
	/*
	 * Returns a description of a special day as a String.
	 * If the day is a regular day, null is returned.
	 */
	public String getDescription() {
		DayType pre = HolidayCalculator.getDayType(getDate());
		String desc = HolidayCalculator.getDescription(getDate());
		
		if (getDayType().equals(pre))
			if (desc=="")
				return null;
			else
				return desc;
		else
			if (getDayType()==DayType.Regular)
				return "Benutzerdefinierter Werktag";
			else
				return "Benutzerdefinierter Feiertag";
	}
	
	public boolean isMeetingDay() {
		return getMonth().isMeetingDay(this);
	}
	
	public String debugString() {
		String result = "";
		int[] d = slots.getDeltas();
		for (int i=0;i<d.length;i++)
			result += ":"+d[i];
		return result;
	}

}
